#include <strings.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <google/protobuf/message.h>
#include <boost/filesystem.hpp>
#include "multi.pb.h"
#include "hmac.h"
#include <openssl/hmac.h>

#define MULTICASTIP "224.42.42.42"
#define CLIENT_MULTICASTPORT 3200
#define BLOB_SIZE 1000

class udp_sender {
public:
	udp_sender(int port) {
		m_sockfd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);

		bzero(&m_servaddr,sizeof(m_servaddr));
		m_servaddr.sin_family = AF_INET;
		m_servaddr.sin_port=htons(port);
		m_servaddr.sin_addr.s_addr=inet_addr(MULTICASTIP);
	}
	void send(std::string data) {
		pthread_mutex_lock(&m_lock);
		sendto(m_sockfd,data.c_str(),data.size(),0,
		       (struct sockaddr *)&m_servaddr,sizeof(m_servaddr));

		pthread_mutex_unlock(&m_lock);
	}

	void send(server::Block const& block) {
		pthread_mutex_lock(&m_lock);
		std::string data;
		block.SerializeToString(&data);
		data.append(hmac(data));
		sendto(m_sockfd,data.c_str(),data.size(),0,
		       (struct sockaddr *)&m_servaddr,sizeof(m_servaddr));
		usleep(10000);

		pthread_mutex_unlock(&m_lock);
	}

private:
	int m_sockfd,m_n;
	struct sockaddr_in m_servaddr,m_cliaddr;
	pthread_mutex_t m_lock;
};

udp_sender sender(CLIENT_MULTICASTPORT);


void* heartbeatSendThread(void *arg) {
	while(1) {
		std::cout << "send" << std::endl;
		server::Block block;
		unsigned int t = static_cast<unsigned int>(time(NULL));
		block.mutable_heartbeat()->set_time(t);
		sender.send(block);
		sleep(1);
	}
	return NULL;
}


int main(int argc, char**argv) {

   /* Our process ID and Session ID */
                pid_t pid, sid;

                pid = fork();
                if (pid < 0)
                {
                        exit(EXIT_FAILURE);
                }

                if (pid > 0)
                {
                        exit(EXIT_SUCCESS);
                }



	srand (time(NULL));


		pthread_t heartbeatProcess;
		pthread_create(&(heartbeatProcess), NULL, &heartbeatSendThread, NULL);


		pthread_join(heartbeatProcess, NULL);


	return 0;
}
